﻿using Microsoft.Extensions.Configuration;
using SHKF.B2C.JuShuiTan.BLL;
using SHKF.B2C.JuShuiTan.Model;
using SHKF.B2C.JuShuiTan.Model.Entity;
using SHKF.B2C.JuShuiTan.Model.Inter;
using SHKF.B2C.JuShuiTan.Network;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace SHKF.B2C.JuShuiTan.Service
{
    public class JSTHttpClient : JSTClient
    {
        private readonly TokenBLL tokenBLL;

        public JSTHttpClient(TokenBLL tokenBLL, IConfiguration Configuration):base()
        {
            CS = Configuration.GetSection("CS").Value;
            base.Init();
            this.tokenBLL = tokenBLL;
        }

        protected override async Task<string> GetToken()
        {
            if (CS == "1")
            {
                this.access_token = "8db141b6d724211b28d2eff2c93fe918"; //access_token(专业版) 
            }
            else
            {
                //聚水潭的token是在平台里生成好的，在erp的数据库里存一份就行 
                TokenEntity tokenInfo = tokenBLL.Get(CompanyID);
                if (tokenInfo != null)
                {
                    int tokenOffice = 1; //一小时误差
                    DateTime now = DateTime.Now;

                    long timestamp = DTUtil.DateTimeToTimeStamp(now.AddHours(tokenOffice)); //一小时误差
                    long expires_in = DTUtil.DateTimeToTimeStamp(tokenInfo.end_time);

                    if (expires_in < timestamp) //如果access_token过期
                    {
                        //如果刷新Token也过期

                        //刷新  
                        tokenInfo = await this.RefreshToken(tokenInfo.refresh_token, tokenInfo.CompanyName);
                        //保存Token
                        if (tokenInfo != null)
                        {
                            access_token = tokenInfo.access_token;
                        }
                        else
                        {

                        }
                    }
                    else
                    {
                        access_token = tokenInfo.access_token;
                    }
                }
            }

            return access_token;
        }

        private async Task<TokenEntity> RefreshToken(string refresh_token, string CompanyName)
        {
            string time = Math.Floor(this.GetTimeStamp()).ToString();

            Dictionary<string,string> ht = new Dictionary<string, string>();
            ht.Add("app_key", this.app_key);
            ht.Add("timestamp", time);
            ht.Add("grant_type", "refresh_token");
            ht.Add("charset", "utf-8");
            ht.Add("refresh_token", refresh_token);
            ht.Add("scope", "all");

            string sign = this.getSign(app_secret, ht);
            ht.Add("sign", sign);

            string text = this.GetParamData(ht);
            StringContent content = new StringContent(text);

            content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
            //charset=UTF-8
            string requestUri = base.BaseAddress.OriginalString + urlRefreshToken;
            HttpResponseMessage httpResponseMessage = await base.PostAsync(requestUri, content);
            if (httpResponseMessage.IsSuccessStatusCode)
            {
                RefreshTokenDto result = await httpResponseMessage.Content.ReadAsAsync<RefreshTokenDto>();
                if (result.code == 0)
                {
                    TokenEntity tokenEntity = new TokenEntity();
                    tokenEntity.start_time = DateTime.Now;
                    tokenEntity.access_token = result.data.access_token;
                    tokenEntity.expires_in = result.data.expires_in;
                    tokenEntity.refresh_token = result.data.refresh_token;
                    tokenEntity.scope = result.data.scope;
                    tokenEntity.CompanyName = CompanyName;
                    tokenEntity.end_time = tokenEntity.start_time.AddSeconds(tokenEntity.expires_in);
                    this.tokenBLL.Save(tokenEntity);
                    return tokenEntity;
                }
                else
                {
                    return null;
                }
            }
            else
            {
                BaseDto error = await httpResponseMessage.Content.ReadAsAsync<BaseDto>();
                return null;
            }
        }
    }
}
